﻿using System;
using System.Linq;
using CH.Reia.Infrastructure.Entity;
using CH.Reia.Infrastructure.Entity.Attribute;

namespace CH.Reia.Infrastructure.Data
{
    public static class Criteria
    {
        public static String Builder(Object criteriaEntity)
        {
            try
            {
                var whereStr = String.Format(" Type = '{0}' ", criteriaEntity.GetType().Name);

                foreach (var propertyInfo in criteriaEntity.GetType().GetProperties())
                {
                    if ((propertyInfo.GetCustomAttributes(typeof(CriteriaMemberAttribute), false).Count() > 0) && (propertyInfo.GetValue(criteriaEntity, null) != null))
                    {
                        if (propertyInfo.PropertyType.FullName.Contains("List"))
                        {

                        }
                        else if (propertyInfo.PropertyType.FullName.Contains("Costruttore"))
                        {
                            var findStr = @" And Content Like Concat('%', (Select 
                                                                           Identifier
                                                                       From 
                                                                           `{0}`
                                                                       Where 
                                                                           {1} ), '%')";

                            var domainStr = (propertyInfo.GetValue(criteriaEntity, null) as IEntity).Domain;

                            if ((!string.IsNullOrEmpty(domainStr)) && (!domainStr.Equals(((IEntity)criteriaEntity).Domain)))
                            {
                                var identifierStr = string.Concat(propertyInfo.GetValue(criteriaEntity, null).GetType().Name, "Id");
                                var contentStr = propertyInfo.GetValue(criteriaEntity, null).GetType().GetProperty(identifierStr).GetValue(propertyInfo.GetValue(criteriaEntity, null), null);

                                whereStr = String.Concat(whereStr, " And Content Like ", String.Format(" '%\"{0}\":\"{1}\"%' ", identifierStr, contentStr));

                                continue;
                            }

                            whereStr = String.Concat(whereStr, string.Format(findStr, ((IEntity)criteriaEntity).Domain, Builder(propertyInfo.GetValue(criteriaEntity, null) as IEntity)));
                        }
                        else if (propertyInfo.PropertyType.Name.Contains("String"))
                        {
                            if (propertyInfo.GetValue(criteriaEntity, null).ToString().IndexOf("=*=") > 0)
                                whereStr = String.Concat(whereStr, " And Content Like ", String.Format(" '%\"{0}\":\"{1}\"%' ", propertyInfo.Name, propertyInfo.GetValue(criteriaEntity, null).ToString().Replace("=*=", string.Empty)));
                            else
                                if (propertyInfo.GetValue(criteriaEntity, null).ToString().IndexOf("%*%") > 0)
                                    whereStr = String.Concat(whereStr, " And Content Like ", String.Format(" '%\"{0}\":{1}' ", propertyInfo.Name, propertyInfo.GetValue(criteriaEntity, null)));
                                else
                                    whereStr = String.Concat(whereStr, " And Content Like ", String.Format(" '%\"{0}\":%{1}%' ", propertyInfo.Name, propertyInfo.GetValue(criteriaEntity, null)));

                        }
                        else if (propertyInfo.PropertyType.Name.Contains("DateTime"))
                        {
                            whereStr = String.Concat(whereStr, " And Content Like ", String.Format(" '%\"{0}\":\"{1}\"%' ", propertyInfo.Name, propertyInfo.GetValue(criteriaEntity, null)));
                        }
                        else if ((propertyInfo.PropertyType.FullName.Contains("Boolean") ||
                                 propertyInfo.PropertyType.FullName.Contains("Int") ||
                                 propertyInfo.PropertyType.FullName.Contains("Int16") ||
                                 propertyInfo.PropertyType.FullName.Contains("Int32")) && (propertyInfo.GetValue(criteriaEntity, null) != null))
                        {
                            whereStr = String.Concat(whereStr, " And Content Like ", String.Format(" '%\"{0}\":{1}%' ", propertyInfo.Name, propertyInfo.GetValue(criteriaEntity, null)));
                        }
                    }

                    if (whereStr.Contains("Content Like") && !whereStr.Contains("And Identifier") && (criteriaEntity.GetType().GetProperty(string.Concat(criteriaEntity.GetType().Name, "Id")).GetValue(criteriaEntity, null) != null))
                    {
                        var identifierStr = criteriaEntity.GetType().GetProperty(string.Concat(criteriaEntity.GetType().Name, "Id")).GetValue(criteriaEntity, null);
                        whereStr = String.Concat(whereStr, string.Format(" And Identifier = '{0}' ", identifierStr));
                    }
                }

                return whereStr;
            }
            catch (Exception)
            {
                return String.Empty;
            }
        }
    }
}